/**
 * 
 * @param { *用户名 } userName      String
 * @param {*密码 } password         String
 * @param {*IP地址 } deviceAddress  String
 * @param {*端口 } wPort            Number
 * @returns Buffer对象的图片
 */

 const ffi = require('ffi-napi');               // 调用动态库的
 const ref = require('ref-napi');               // 将Buffer实例变成“指针”
 const refStruct = require('ref-struct-napi');  // 创建符合 ABI 的“ 结构 在缓冲区之上 ”
 const refArray = require('ref-array-napi');    // 在缓冲区之上创建 C 类型的“数组”
 var path = require('path');

 // 定义结构类型
 var LoginInfo = refStruct({
    'sDeviceAddress': refArray('byte', 129),
    'byUseTransport': ref.types.uint8, 
    'wPort': ref.types.uint16,
    'sUserName': refArray('byte', 64),
    'sPassword': refArray('byte', 64),
    'cbLoginResult': ref.types.int64,
    'pUser': ref.types.int64,
    'bUseAsynLogin': ref.types.int,
    'byProxyType': ref.types.uint8, 
    'byUseUTCTime': ref.types.uint8, 
    'byLoginMode': ref.types.uint8,
    'byHttps': ref.types.uint8,
    'iProxyID': ref.types.long, 
    'byVerifyMode': ref.types.uint8,
    'byRes3': refArray('byte', 119)
})

// 设备信息
var deviceInfo = refStruct({
    byteData: refArray('byte', 344)
});

// 图片信息
var picInfo = refStruct({
    "wPicSize": ref.types.uint16,
    "wPicQuality": ref.types.uint16
})

var dll;

exports.Camera_Open = function (userName, password, deviceAddress, wPort) {
    // 登录参数，包括设备地址、登录用户、密码等
    var tLogin = new LoginInfo({
        sUserName:[...userName],
        sPassword:[...password],
        sDeviceAddress:[...deviceAddress],
        wPort: wPort,
    });

    // 设备信息
    var tDev = new deviceInfo({});

    var libPath = path.join(__dirname, '.', 'dll');
    var libName = process.platform === "win32" ? 'HCNetSDK' : 'libHCNetSDK';
    process.env.PATH = `${process.env.PATH}${path.delimiter}${libPath}`;

    // 要调用的dll
    dll = ffi.Library(libName,{
        "NET_DVR_Init": ['bool', []],
        "NET_DVR_Login_V40": ['long', [ref.refType(LoginInfo), ref.refType(deviceInfo)]], // ref.refType(对象|字符串类型)  生成C++中对应的指针，例如生成int类型的指针： ref.refType(ref.types.int)
        'NET_DVR_CaptureJPEGPicture': ['int', ['int', 'int', 'pointer', 'string']],
        'NET_DVR_CaptureJPEGPicture_NEW': ['int', ['int', 'int', 'char*', 'char*', 'int', 'uint*']],
        'NET_DVR_GetLastError':['int',[]],
        'NET_DVR_Cleanup':['bool',[]]
    })

    // 初始化SDK
    var Result = dll.NET_DVR_Init();
    // console.log(Result);

    // 实时预览
    var loginResult = dll.NET_DVR_Login_V40(tLogin.ref(), tDev.ref());

    // 返回登录结果
    return loginResult;
}

exports.Camera_ImgCap = function (loginResult, buffer) {
    // 创建照片信息
    var tPic = new picInfo({});

    var lengthpointer = ref.alloc('uint');

    // 保存图片到缓冲区
    var Result = dll.NET_DVR_CaptureJPEGPicture_NEW(
        loginResult,    // NET_DVR_Login_V40等登录接口的返回值 
        1,              // 通道号
        tPic.ref(),     // JPEG图像参数 
        buffer,         // JPEG数据的缓冲区 
        1024*1024,      // 输入缓冲区大小
        lengthpointer   // 返回图片数据的大小
    );

    // 返回图片大小
    return lengthpointer.deref();
}

exports.Camera_Close = function () {
    var Result = dll.NET_DVR_Cleanup();
    return Result;
}